using System;
using System.IO;
using System.Windows.Controls;
using YouVisio.Silverlight.TextDiff.Extensions;

namespace YouVisio.Silverlight.TextDiff
{
    public class InputAccessor : IInputAccessor
    {

        public InputAccessor(ISettingsSource settings)
        {
            Settings = settings;
        }

        protected ISettingsSource Settings { get; private set; }

        public Tuple<string, string> GetText(ITextDiffViewerUI ui)
        {
            return new Tuple<string, string>(ui.GetLeftText(), ui.GetRightText());
        }

        public bool SelectFile(TextDiffViewerUI ui, bool isLeft)
        {
            var openFile = new OpenFileDialog
            {
                Filter = Settings.Label_TextOrSourceFiles+"|"+Settings.AllowedFileTypes,
                FilterIndex = 1,
                Multiselect = false
            };
            var okClicked = openFile.ShowDialog();
            if (okClicked == true)
            {
                var fileName = openFile.File.Name;
                if (!IsValidFileName(ui, fileName))
                {
                    return false;
                }
                string result;
                using(var stream = openFile.File.OpenRead())
                {
                    if (!IsValidFileSize(ui, stream.Length))
                    {
                        stream.Close();
                        return false;
                    }
                
                    using (var reader = new StreamReader(stream))
                    {
                        result = reader.ReadToEnd();
                    }
                    stream.Close();
                }
                if (result != null && !IsValidStringSize(ui, result.Length)) { return false; }
                if(isLeft)
                {
                    ui.SetLeftText(result);
                    ui.SetLeftFileName(fileName);
                }
                else
                {
                    ui.SetRightText(result);
                    ui.SetRightFileName(fileName);
                }
            }
            return true;
        }

        public bool SetFiles(TextDiffViewerUI ui, FileInfo[] files, bool isLeft)
        {
            if(files.Length == 1)
            {
                var nameAndContent = GetNameAndContent(ui, files[0]);
                if (nameAndContent == null) { return false; }
                if(isLeft)
                {
                    ui.SetLeftFileName(nameAndContent.Item1);
                    ui.SetLeftText(nameAndContent.Item2);
                }
                else
                {
                    ui.SetRightFileName(nameAndContent.Item1);
                    ui.SetRightText(nameAndContent.Item2);
                }
            }
            else if(files.Length > 1)
            {
                var leftNameAndContent = GetNameAndContent(ui, files[0]);
                if (leftNameAndContent == null) { return false; }
                ui.SetLeftFileName(leftNameAndContent.Item1);
                ui.SetLeftText(leftNameAndContent.Item2);
                var rightNameAndContent = GetNameAndContent(ui, files[1]);
                if (rightNameAndContent == null) { return false; }
                ui.SetRightFileName(rightNameAndContent.Item1);
                ui.SetRightText(rightNameAndContent.Item2);
            }
            return true;
        }

        private Tuple<string, string> GetNameAndContent(TextDiffViewerUI ui, FileInfo fi)
        {
            if (!IsValidFileName(ui, fi.Name)) { return null; }
            if (!IsValidFileSize(ui, fi.Length)) { return null; }
            string result;
            using(var stream = fi.OpenRead())
            {
                using (var reader = new StreamReader(stream))
                {
                    result = reader.ReadToEnd();
                }
                stream.Close();
            }
            if (!IsValidStringSize(ui, result.Length)) { return null; }
            return new Tuple<string, string>(fi.Name, result);
        }


        private bool IsValidFileName(TextDiffViewerUI ui, string fileName)
        {
            if (!Settings.IsAllowedFileName(fileName))
            {
                ui.SetErrorMessage(Settings.Label_Error_FilesWithThatExtensionNotAllowed.Args(Path.GetExtension(fileName)));
                return false;
            }
            return true;
        }
        private bool IsValidFileSize(TextDiffViewerUI ui, long size)
        {
            if (size > Settings.MaxAllowedFileSizeInBytes)
            {
                ui.SetErrorMessage(Settings.Label_Error_FilesWithThatSizeNotAllowed.Args(Settings.MaxAllowedFileSizeInBytes * 1024));
                return false;
            }
            return true;
        }
        private bool IsValidStringSize(TextDiffViewerUI ui, long size)
        {
            if (size > Settings.MaxAllowedStringSize)
            {
                ui.SetErrorMessage(Settings.Label_Error_StringsWithThatSizeNotAllowed.Args(Settings.MaxAllowedStringSize)); 
                return false;
            }
            return true;
        }
    }
}